home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 11 / develop 11 code / The NetWork Project / Examples (Sources) / Ping.p < prev    next >
Encoding:
Text File  |  1992-07-15  |  8.7 KB  |  330 lines  |  [TEXT/MPS ]

  1. { © Copyright 1989,1990,1991 The NetWork Project, StatLab Heidelberg. 
  2.   © Copyright 1989,1990,1991 Joachim Lindenberg, Karlsruhe. All rights reserved. }
  3.  
  4. program Ping;
  5.  
  6. uses     MemTypes, 
  7.         QuickDraw,
  8.         OSIntf,
  9.         ToolIntf,
  10.         PackIntf,
  11.         Traps,
  12.         SysEqu,
  13.         
  14.         NetWork,
  15.         NetWorkLookup;
  16.  
  17. PROCEDURE InitToolBox;
  18. VAR
  19.     i : integer;
  20.     p : GrafPtr;
  21.     m : MenuHandle;
  22.  
  23. BEGIN
  24.     MaxApplZone;
  25.     FOR i := 1 TO 10 DO
  26.     MoreMasters;
  27.     InitGraf(@thePort);                {initialize QuickDraw}
  28.     InitFonts;                           {initialize Font Manager}
  29.     InitWindows;                       {initialize Window Manager}
  30.     InitMenus;                           {initialize Menu Manager}
  31.     TEInit;                            {initialize TextEdit}
  32.     InitDialogs(NIL);                   {initialize Dialog Manager}
  33.     InitCursor;                        {call QuickDraw to make cursor (pointer) an arrow}
  34.  
  35.     m := GetMenu (256);
  36.     AddResMenu (m, 'DRVR');
  37.     InsertMenu (m, 0);
  38.     m := GetMenu (257); InsertMenu (m, 0);
  39.     m := GetMenu (258); InsertMenu (m, 0);
  40.     m := GetMenu (259); InsertMenu (m, 0);
  41.     m := GetMenu (260); InsertMenu (m, 0);
  42.     DrawMenuBar;
  43.  
  44. END;
  45.  
  46. var done,                { got cmd-Q }
  47.     frontmost,            { frontmost process }
  48.     beep : boolean;        { beep on message }
  49.  
  50.     others : integer;    { number of available NetWork Processors }
  51.  
  52.     MySelf : MsgAddr; signature : longint;
  53.     last : longint;        { last address we sent something to }
  54.     nexttime, interval : longint; { for automatic modes }
  55.     mode, intset, msgsize : integer; { mode, interval, and size menu settings }
  56.  
  57.     { this function sends a broadcast message on all available transports }
  58.  
  59. type CharArray = packed array [0..0] of char; CharPtr = ^CharArray;
  60.  
  61. procedure ComplexBC (buffer : Ptr; size : integer);
  62. var i : integer; trp : TransportPtr;
  63.     Msg : MsgRec; NewMsg : MsgPtr; p : CharPtr;
  64. begin
  65.     i := 0; p := CharPtr (@Msg); fillchar (p^, sizeof (Msg), chr (0));
  66.     Msg.MsgSource := MySelf; Msg.MsgDest.p := signature;
  67.     while GetTransport (trp, i) = noErr do with trp^, Msg do begin
  68.         if TransportBCAddr <> 0 then begin
  69.             MsgSource.a := TransportAddr; MsgReply := MsgSource;
  70.             MsgDest.a := TransportBCAddr; MsgTrpPtr := Trp;
  71.             MsgReference := TimeStamp; MsgUserRefCon := 0;
  72.             MsgCorePtr := buffer; MsgCoreSize := size;
  73.             CheckError ('Complex BC', SendMsg (@Msg, NewMsg));
  74.         end;
  75.         i := i + 1;
  76.     end;        
  77. end;
  78.  
  79. procedure DoPing;
  80. var Msg : MsgPtr; Dest : MsgAddr; p : Ptr; i : integer;
  81. begin
  82.     p := NewPtr (msgsize);
  83.     if p = nil then exit (DoPing);
  84.     for i := 0 to msgsize-1 do CharPtr (p)^[i] := chr (i);
  85.     if mode = 5 then ComplexBC (p, msgsize)
  86.     else begin 
  87.         case mode of
  88.             1 : Dest.a := 0; { local }
  89.             2 : Dest.a := NlRandom; { 2, 3 will result in local, if no partners }
  90.             3 : begin
  91.                 last := NlNext (last); Dest.a := last;
  92.             end; 
  93.             4 : Dest.a := -1; { broadcast }
  94.         end;    
  95.         Dest.p := signature;
  96.         CheckError ('DoPing', PostMsg (Msg, nil, 0, TickCount {TimeStamp}, Dest, MySelf, nil, 0, p, msgsize));
  97.     end;
  98. end;
  99.  
  100. procedure KillMsg (Msg : MsgPtr);
  101. var buffer : Ptr;
  102. begin
  103.     buffer := Msg^.MsgCorePtr; CheckError ('KillMsg', DestroyMsg (Msg));
  104.     if buffer <> nil then DisposPtr (buffer);
  105. end;
  106.  
  107. procedure ReceiveMsg (Msg : MsgPtr);
  108. var buffer : Ptr;
  109. begin
  110.     buffer := NewPtr (Msg^.MsgCoreSize);
  111.     if buffer = nil then begin
  112.         LogMsg ('MemFail', Msg); KillMsg (Msg)
  113.     end
  114.     else begin
  115.         CheckError ('Accept', AcceptMsg (Msg, buffer, Msg^.MsgCoreSize));
  116.     end;
  117. end;
  118.  
  119. procedure HandleMsg (Msg : MsgPtr);
  120. var i : integer; p : Ptr; 
  121. begin
  122.     with Msg^ do 
  123.     if (MsgResult < 0) | (BAnd (MsgCmd, tMinorMask) >= tTimeout) then KillMsg (Msg)
  124.     else case BAnd (MsgCmd, tMajorMask) of
  125.         tListen : begin
  126.             CheckError ('GetMsg', GetMsg (Msg, nil, 0)); 
  127.             if Visible & Spare then
  128.             case Alert (257, nil) of
  129.                 OK : ReceiveMsg (Msg);
  130.                 Cancel : begin
  131.                             LogMsg ('Deny', Msg); CheckError ('Deny', DestroyMsg (Msg));
  132.                         end;
  133.             end
  134.             else begin 
  135.                 ReceiveMsg (Msg);
  136.                 if beep then SysBeep (1);
  137.             end;
  138.         end;
  139.         tGet : ProgramBreak ('how did we get there?');
  140.         tAccept  : begin
  141.             p := MsgCorePtr;
  142.             if (MsgResult = 0) then
  143.             for i := 0 to MsgCoreSize - 1 do
  144.             if CharPtr (p)^ [i] <> chr (BAnd (i, 255)) then begin
  145.                 ProgramBreak ('message verify error'); LEAVE;
  146.             end;
  147.             KillMsg (Msg);
  148.         end;
  149.         tPost : KillMsg (Msg);
  150.     end;
  151. end;
  152.  
  153. procedure About;
  154. begin
  155.     if Alert (256, nil) = Ok then;
  156. end;
  157.  
  158. procedure SetCreator (var signature : longint);
  159. var d : DialogPtr; n, t : integer; s : Str255; h : Handle; box : Rect;
  160. begin
  161.     d := GetNewDialog (258, nil, WindowPtr (-1));
  162.     s := 'NetP'; BlockMove (@signature, @s[1], 4);
  163.     GetDItem (d, 3, t, h, box);
  164.     SetIText (h, s); SelIText (d, 3, 0, 32767);
  165.     repeat
  166.         ModalDialog (nil, n);
  167.         GetDItem (d, 3, t, h, box);
  168.         GetIText (h, s);
  169.     until (n = 2) | (length (s) = 4);
  170.     if n = Ok then BlockMove (@s[1], @signature, 4);
  171.     DisposDialog (d);
  172. end;
  173.  
  174. procedure DoMenu (menu : Point);
  175. var  s : Str255; l : longint; i : integer;
  176. begin
  177.     {    HiliteMenu (menu.v); { in case CmdKey }
  178.     case menu.v of
  179.         256 : { apple menu }
  180.         if menu.h = 1 then About
  181.         else begin
  182.             GetItem (GetMHandle (256), menu.h, s);
  183.             CheckError ('OpenDeskAcc', OpenDeskAcc (s));
  184.         end;
  185.         257 : case menu.h of
  186.             1 : SetCreator (signature);
  187.             3 : begin
  188.                 beep := not beep;
  189.                 CheckItem (GetMHandle (257), 3, beep);
  190.             end;
  191.             5 : DoPing;
  192.             6 : done := true;
  193.         end;
  194.         258 : begin
  195.             CheckItem (GetMHandle (258), mode, false);
  196.             mode := menu.h;
  197.             CheckItem (GetMHandle (258), mode, true);
  198.         end;
  199.         259 : begin
  200.             CheckItem (GetMHandle (259), intset, false);
  201.             intset := menu.h;
  202.             CheckItem (GetMHandle (259), intset, true);
  203.             case intset of
  204.                 3 : interval := 6;
  205.                 4 : interval := 60;
  206.                 5 : interval := 600;
  207.                 6 : interval := 3600;
  208.                 7 : interval := 7200;
  209.             end;
  210.             nexttime := TickCount + interval;
  211.         end;
  212.         260 : begin
  213.             for i := 1 to CountMItems (GetMHandle (260)) do CheckItem (GetMHandle (260), i, false);
  214.             CheckItem (GetMHandle (260), menu.h, true);
  215.             GetItem (GetMHandle (260), menu.h, s);
  216.             i := pos (' ', s); if i <> 0 then s [0] := chr (i-1);
  217.             l := 0; StringToNum (s, l);
  218.             msgsize := l;
  219.         end;
  220.  
  221.     end;
  222.     HiliteMenu (0);
  223. end;
  224.  
  225. { GetSleep calculates the sleep interval. It takes the following facts into account :
  226.     - whether ping is front or back application
  227.     - whether the lookup task needs time (note that nlsleep returns maxlongint if no task)
  228.     - whether one of the automatic modes requires a wakeup.
  229. }
  230.  
  231. function GetSleep : longint;
  232. var maxsleep, sleep : longint;
  233. begin
  234.     if frontmost then maxsleep := 60 else maxsleep := maxlongint;
  235.     sleep := NlGetSleep; if sleep < maxsleep then maxsleep := sleep;
  236.     
  237.     if intset <> 1 then begin { automatic modes }
  238.         sleep := nexttime - TickCount; if sleep < 0 then sleep := 0;
  239.         if sleep < maxsleep then maxsleep := sleep;    
  240.     end;
  241.     GetSleep := maxsleep;
  242. end;
  243.  
  244. procedure HandleEvents;
  245. var w : windowPtr;
  246.     ev : EventRecord; 
  247. begin
  248.     if WaitNextEvent (EveryEvent, ev, GetSleep, nil) then
  249.     case ev.what of
  250.         mouseDown : case FindWindow (ev.where, w) of
  251.             inMenuBar : begin
  252.                 DoMenu (Point (MenuSelect (ev.where)));
  253.             end;
  254.             inSysWindow : SystemClick (ev,w);
  255.         end;
  256.         keyDown : if BAnd (ev.modifiers, cmdKey) <> 0 then
  257.         DoMenu (Point (MenuKey (chr (BAnd (ev.message, 255))))); 
  258.         NetWorkEvt : HandleMsg (MsgPtr (ev.message));
  259.         app4Evt : if BAnd (ev.message, $ff000000) = $01000000 then frontmost := odd (ev.message);
  260.     end;
  261. end;
  262.  
  263. { sample stack setup sequence in case we are faceless…
  264.   - default stack sizes are
  265.     24KB if Colour Quickdraw is installed and the application is not faceless
  266.     8KB if Colour Quickdraw is not installed and…
  267.     2KB if the application is faceless
  268.   - NetWork Processor requires up to 2.5KB of stack space to operate correctly
  269. }
  270.  
  271. procedure InitStack;
  272. type LongPtr = ^ longint;
  273. begin
  274.     if LongPtr (CurStackBase)^ - LongInt (GetApplLimit) < 4096 then
  275.     SetApplLimit (Ptr (LongPtr (CurStackBase)^ - 4096))
  276. end;
  277.  
  278. var s : str255;
  279.     err : integer;
  280.     sysv : longint;
  281.  
  282. begin
  283.     InitStack; InitToolBox;
  284.  
  285.     done := false; beep := false; last := 0; others := -1; { impossible count }
  286.  
  287.     err := InitNetWork (NetWorkEvt);
  288.     if err <> noErr then begin
  289.         CheckError ('InitNetWork', err);
  290.         ExitToShell; { this program is useless without }
  291.     end;
  292.  
  293.     CheckError ('NlInit', NlInit);
  294.  
  295.     MySelf := GetNetWorkAddr; signature := MySelf.p;
  296.  
  297.     DoMenu (Point ($01010003)); { beep }
  298.     DoMenu (Point ($01020002)); { random }
  299.     DoMenu (Point ($01030001)); { manual }
  300.     DoMenu (Point ($01040001)); { 0 size }
  301.  
  302.     if Master then begin
  303.         CheckError ('NlStart', NlStart); 
  304.         CheckError ('NlRegister', NlRegister ('','Network Ping'));
  305.     end;
  306.  
  307.     while (not done) do begin
  308.         CheckError ('NlTask', NlTask);
  309.         HandleEvents;
  310.  
  311.         if Master & spare & (others <> NlCount) then begin
  312.             others := NlCount; NumToString (others, s); insert ('Ping : Number of avail partners = ', s, 1);
  313.             LogStrTime (s);
  314.         end;
  315.  
  316.         if (intset <> 1) & (nexttime <= TickCount) then begin
  317.             DoPing;
  318.             nexttime := nexttime + interval;
  319.         end;
  320.  
  321.     end;
  322.  
  323.     if Master then begin
  324.         CheckError ('NlStop', NlStop);
  325.         CheckError ('NlDeregister', NlDeregister);
  326.     end;
  327.     {CheckError ('NlExit', NlExit);
  328.     CheckError ('ExitNetWork', ExitNetWork);}
  329. end.
  330.